package com.ruifu.proj.service.impl;

import com.ruifu.common.po.PmPlanVer;
import com.ruifu.common.po.PmPtMain;
import com.ruifu.proj.dto.ptmain.PmPlanVerDTO;
import com.ruifu.proj.enums.PlanEnum;
import com.ruifu.proj.mapper.PmPlanVerMapper;
import com.ruifu.proj.mapper.PmPtMainMapper;
import com.ruifu.proj.service.PmPlanVerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;


/**
 * @author nyr
 * @create 2019/8/7
 */
@Service
@Transactional(rollbackFor = Exception.class)
@SuppressWarnings("all")
public class PmPlanVerServiceImpl implements PmPlanVerService {
    @Autowired(required = false)
    private PmPlanVerMapper pmPlanVerMapper;

    @Autowired
    private PmPtMainMapper pmPtMainMapper;

    @Autowired
    private PmPtMainServiceImpl pmPtMainService;

    @Override
    public void updatePvStatus(List<PmPlanVerDTO> pmPlanVerDTOList) {
        //判断数据是否为空
        if (pmPlanVerDTOList == null || pmPlanVerDTOList.size() == 0) {
            throw new RuntimeException("没有版本记录，无法批准");
        }
        //获取最新版本
        PmPlanVerDTO pmPlanVerDTO = pmPlanVerDTOList.get(pmPlanVerDTOList.size() - 1);
        //判断状态是否允许批准
        if (PlanEnum.EDITING.getCode().equals(pmPlanVerDTO.getPvStatus())) {
            throw new RuntimeException("计划仍在编辑中，无法再次批准");
        }
        if (PlanEnum.APPROVED.getCode().equals(pmPlanVerDTO.getPvStatus())) {
            throw new RuntimeException("最新版本已经批准，无法再次批准");
        }
        //2020.5.22  撤销状态不能批准
        if (PlanEnum.REVOKED.getCode().equals(pmPlanVerDTO.getPvStatus())){
            throw new RuntimeException("最新版本为撤销状态不能被批准");
        }

        //从数据库中获取PO
        PmPlanVer pmPlanVer = pmPlanVerMapper.findById(pmPlanVerDTO.getPvId());

        /*2020.5.16增加对时间的校验*/

        //对应的项目任务
        PmPtMain pmPtMain = pmPtMainMapper.findById(pmPlanVer.getPvPtid());
        //该项目本来的天数
        int oldDays = getDays(pmPtMain.getPtPlanStart(), pmPtMain.getPtPlanEnd());

        //对变更时间做校验
        Date startime = pmPlanVerDTO.getPvStartime();//开始时间
        Date endtime = pmPlanVerDTO.getPvEndtime();//结束时间
        int planDays = getDays(startime, endtime);
        int i = planDays - oldDays;//计划天数与原来天数相差天数

        //查询任务的父任务
        PmPtMain parent = pmPtMainMapper.findById(pmPtMain.getPtPId());

        //递归查询任务所属根项目
        PmPtMain root = pmPtMainService.recursionProject(pmPtMain.getPtId());


        if (startime.before(parent.getPtPlanStart()) || endtime.after(parent.getPtPlanEnd())) {
            throw new RuntimeException("申请计划的开始时间或结束时间超出父项目/任务时间范围");
        }

        if (startime.before(root.getPtPlanStart()) || endtime.after(root.getPtPlanEnd())) {
            throw new RuntimeException("申请计划的开始时间或结束时间超出根项目/任务时间范围");
        }

        //根项目的计划总时间
        int parentProDays = getDays(root.getPtPlanStart(), root.getPtPlanEnd());

        List<PmPtMain> pmPtMainList = pmPtMainMapper.findByPtPIdOrder(pmPtMain.getPtPId());
        int sum = 0;
        for (PmPtMain ptMain : pmPtMainList) {
            //每个任务的天数累加
            sum += getDays(ptMain.getPtPlanStart(), ptMain.getPtPlanEnd());
        }
        sum+=i;
        if (sum > parentProDays) {
            throw new RuntimeException("计划变更后的任务的总时间已超出根项目计划时间！ ");
        }

        /*2020.5.16增加对时间的校验*/


        //修改批准状态
        pmPlanVer.setPvStatus(PlanEnum.APPROVED.getCode());
        //修改批准时间
        pmPlanVer.setPvPubdate(new Date());
        //更新到数据库
        pmPlanVerMapper.update(pmPlanVer);
        /**
         * 批准后插入数据库
         */

        pmPtMain.setPtPlanStart(pmPlanVer.getPvStartime());
        pmPtMain.setPtPlanEnd(pmPlanVer.getPvEndtime());
        pmPtMain.setPtDays(pmPlanVer.getPvDuration());
        pmPtMain.setPtCost(pmPlanVer.getPvBudget());
        pmPtMain.setPtCostunit(pmPlanVer.getPvCostunit());
        pmPtMain.setPtLastUpdate(new Date());
        //保存项目到数据库
        pmPtMainMapper.updatePmPtMain(pmPtMain);
    }

    public int getDays(Date start, Date end) {
        return (int) ((end.getTime() - start.getTime()) / (1000 * 3600 * 24));
    }

    @Override
    public void newVersion(List<PmPlanVerDTO> pmPlanVerDTOList) {
        //判断数据是否为空
        if (pmPlanVerDTOList == null || pmPlanVerDTOList.size() == 0) {
            throw new RuntimeException("没有版本记录，无法升版");
        }
        PmPlanVerDTO pmPlanVerDTO = pmPlanVerDTOList.get(pmPlanVerDTOList.size() - 1);
        //判断状态是否允许批准
        if (!PlanEnum.APPROVED.getCode().equals(pmPlanVerDTO.getPvStatus())) {
            throw new RuntimeException("最新版本未批准，无法升版");
        }
        //从数据库中获取PO
        PmPlanVer pmPlanVer = pmPlanVerMapper.findById(pmPlanVerDTO.getPvId());
        //清空主键
        pmPlanVer.setPvId(null);
        //修改批准状态
        pmPlanVer.setPvStatus(PlanEnum.APPROVED.getCode());
        //清空批准时间
        pmPlanVer.setPvPubdate(null);
        //修改序号
        pmPlanVer.setPvOrder(pmPlanVerDTO.getPvOrder() + 1);
        //更新到数据库
        pmPlanVerMapper.insert(pmPlanVer);
    }

    @Override
    public void revoke(Long pvId) {
        PmPlanVer pmPlanVer = pmPlanVerMapper.findById(pvId);
        if (pmPlanVer==null){
            throw new RuntimeException("参数异常，无此变更计划");
        }
        if (!pmPlanVer.getPvStatus().equals(PlanEnum.WAITING_AUDIT.getCode())){
            throw new RuntimeException("只能撤销状态为待审核的计划变更");
        }
        //撤销
        pmPlanVer.setPvStatus(PlanEnum.REVOKED.getCode());
        pmPlanVerMapper.update(pmPlanVer);
    }
}
